const mongoose = require('mongoose');

const coordinatesSchema = new mongoose.Schema({
  latitude: {
    type: Number,
    min: -90,
    max: 90
  },
  longitude: {
    type: Number,
    min: -180,
    max: 180
  }
}, { _id: false });

const originSchema = new mongoose.Schema({
  province: {
    type: String,
    required: true,
    trim: true,
    maxlength: 50
  },
  city: {
    type: String,
    required: true,
    trim: true,
    maxlength: 50
  },
  county: {
    type: String,
    trim: true,
    maxlength: 50
  },
  village: {
    type: String,
    trim: true,
    maxlength: 100
  },
  coordinates: coordinatesSchema,
  address: {
    type: String,
    maxlength: 200
  }
}, { _id: false });

const qualityReportSchema = new mongoose.Schema({
  reportId: {
    type: String,
    trim: true,
    maxlength: 50
  },
  reportUrl: {
    type: String,
    match: [/^https?:\/\/.+/, 'Invalid report URL']
  },
  reportHash: {
    type: String,
    match: [/^0x[a-fA-F0-9]{64}$/, 'Invalid hash format']
  },
  testResults: {
    moistureContent: {
      type: Number,
      min: 0,
      max: 100
    },
    pesticidesLevel: {
      type: Number,
      min: 0
    },
    heavyMetals: mongoose.Schema.Types.Mixed,
    microorganisms: mongoose.Schema.Types.Mixed
  },
  testDate: Date,
  certifyingOrg: {
    type: String,
    maxlength: 100
  }
}, { _id: false });

const productionSchema = new mongoose.Schema({
  farmerId: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'User',
    required: true
  },
  farmerAddress: {
    type: String,
    required: true,
    match: [/^0x[a-fA-F0-9]{40}$/, 'Invalid Ethereum address']
  },
  origin: {
    type: originSchema,
    required: true
  },
  harvestDate: {
    type: Date,
    required: true,
    validate: {
      validator: function(date) {
        return date <= new Date();
      },
      message: 'Harvest date cannot be in the future'
    }
  },
  processingMethod: {
    type: String,
    trim: true,
    maxlength: 200
  },
  qualityReport: qualityReportSchema,
  certifications: [{
    type: String,
    match: [/^https?:\/\/.+/, 'Invalid certification URL']
  }],
  recordedAt: {
    type: Date,
    default: Date.now
  },
  blockchainHash: {
    type: String,
    match: [/^0x[a-fA-F0-9]{64}$/, 'Invalid transaction hash']
  }
}, { _id: false });

const logisticsSchema = new mongoose.Schema({
  logisticsId: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'User',
    required: true
  },
  logisticsAddress: {
    type: String,
    required: true,
    match: [/^0x[a-fA-F0-9]{40}$/, 'Invalid Ethereum address']
  },
  stage: {
    type: String,
    required: true,
    enum: ['pickup', 'transit', 'warehouse', 'delivery'],
    trim: true
  },
  location: {
    address: {
      type: String,
      required: true,
      maxlength: 200
    },
    coordinates: coordinatesSchema
  },
  temperature: {
    min: Number,
    max: Number,
    average: Number
  },
  humidity: {
    min: Number,
    max: Number,
    average: Number
  },
  startTime: {
    type: Date,
    required: true
  },
  endTime: Date,
  vehicle: {
    type: {
      type: String,
      trim: true,
      maxlength: 50
    },
    plateNumber: {
      type: String,
      trim: true,
      maxlength: 20
    },
    driverName: {
      type: String,
      trim: true,
      maxlength: 50
    }
  },
  notes: {
    type: String,
    maxlength: 500
  },
  images: [{
    type: String,
    match: [/^https?:\/\/.+/, 'Invalid image URL']
  }],
  recordedAt: {
    type: Date,
    default: Date.now
  },
  blockchainHash: {
    type: String,
    match: [/^0x[a-fA-F0-9]{64}$/, 'Invalid transaction hash']
  }
});

const salesSchema = new mongoose.Schema({
  merchantId: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'User',
    required: true
  },
  merchantAddress: {
    type: String,
    required: true,
    match: [/^0x[a-fA-F0-9]{40}$/, 'Invalid Ethereum address']
  },
  storeInfo: {
    storeName: {
      type: String,
      required: true,
      trim: true,
      maxlength: 100
    },
    storeAddress: {
      type: String,
      required: true,
      maxlength: 200
    },
    storeType: {
      type: String,
      required: true,
      enum: ['physical', 'online'],
      trim: true
    }
  },
  receiveDate: {
    type: Date,
    required: true
  },
  sellDate: Date,
  price: {
    wholesale: {
      type: Number,
      min: 0
    },
    retail: {
      type: Number,
      min: 0
    }
  },
  quantity: {
    received: {
      type: Number,
      required: true,
      min: 0
    },
    sold: {
      type: Number,
      default: 0,
      min: 0
    },
    remaining: {
      type: Number,
      min: 0
    }
  },
  storageConditions: {
    temperature: String,
    humidity: String,
    lightCondition: String
  },
  qrCode: {
    type: String,
    match: [/^https?:\/\/.+/, 'Invalid QR code URL']
  },
  recordedAt: {
    type: Date,
    default: Date.now
  },
  blockchainHash: {
    type: String,
    match: [/^0x[a-fA-F0-9]{64}$/, 'Invalid transaction hash']
  }
});

const teaBatchSchema = new mongoose.Schema({
  batchId: {
    type: String,
    required: true,
    unique: true,
    trim: true,
    match: [/^[A-Z0-9]{10,20}$/, 'Invalid batch ID format']
  },
  blockchainTxHash: {
    type: String,
    unique: true,
    sparse: true,
    match: [/^0x[a-fA-F0-9]{64}$/, 'Invalid transaction hash']
  },
  name: {
    type: String,
    required: true,
    trim: true,
    maxlength: 100
  },
  variety: {
    type: String,
    required: true,
    trim: true,
    maxlength: 50
  },
  grade: {
    type: String,
    trim: true,
    enum: ['特级', '一级', '二级', '三级', '其他'],
    maxlength: 20
  },
  description: {
    type: String,
    maxlength: 1000
  },
  images: [{
    type: String,
    match: [/^https?:\/\/.+/, 'Invalid image URL']
  }],
  
  // 生产阶段
  production: productionSchema,
  
  // 物流阶段
  logistics: [logisticsSchema],
  
  // 销售阶段
  sales: [salesSchema],
  
  // 状态追踪
  status: {
    type: String,
    required: true,
    enum: ['created', 'production', 'logistics', 'sales', 'consumed'],
    default: 'created'
  },
  currentStage: {
    type: String,
    enum: ['production', 'logistics', 'sales', 'consumed'],
    default: 'production'
  },
  
  // 区块链相关
  contractAddress: {
    type: String,
    match: [/^0x[a-fA-F0-9]{40}$/, 'Invalid contract address']
  },
  totalTransactions: {
    type: Number,
    default: 0,
    min: 0
  },
  
  // 创建者信息
  createdBy: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'User',
    required: true
  },
  
  // 访问控制
  isPublic: {
    type: Boolean,
    default: true
  },
  
  // 统计信息
  views: {
    type: Number,
    default: 0,
    min: 0
  },
  
  // 质量评级
  qualityScore: {
    type: Number,
    min: 0,
    max: 100
  }
}, {
  timestamps: true,
  toJSON: {
    transform: function(doc, ret) {
      // 添加虚拟字段
      ret.totalLogisticsRecords = ret.logistics ? ret.logistics.length : 0;
      ret.totalSalesRecords = ret.sales ? ret.sales.length : 0;
      return ret;
    }
  }
});

// 索引定义 - 避免重复索引
teaBatchSchema.index({ batchId: 1 }, { unique: true, name: 'idx_batchId_unique' });
teaBatchSchema.index({ blockchainTxHash: 1 }, { sparse: true, unique: true, name: 'idx_blockchainTxHash_sparse' });
teaBatchSchema.index({ 'production.farmerId': 1 }, { name: 'idx_production_farmerId' });
teaBatchSchema.index({ status: 1, createdAt: -1 }, { name: 'idx_status_createdAt' }); // 合并单独的status和createdAt索引
teaBatchSchema.index({ currentStage: 1 }, { name: 'idx_currentStage' });
teaBatchSchema.index({ 'production.harvestDate': -1 }, { name: 'idx_production_harvestDate' });
teaBatchSchema.index({ variety: 1, grade: 1 }, { name: 'idx_variety_grade' }); // 合并单独的variety和grade索引
teaBatchSchema.index({ createdBy: 1 }, { name: 'idx_createdBy' });

// 文本搜索索引
teaBatchSchema.index({
  name: 'text',
  variety: 'text', 
  description: 'text',
  'production.origin.province': 'text',
  'production.origin.city': 'text'
}, { name: 'idx_text_search' });

// 虚拟字段
teaBatchSchema.virtual('qrCodeData').get(function() {
  return {
    batchId: this.batchId,
    name: this.name,
    variety: this.variety,
    harvestDate: this.production?.harvestDate,
    origin: this.production?.origin
  };
});

// 中间件：更新剩余数量
salesSchema.pre('save', function(next) {
  if (this.quantity.received && this.quantity.sold >= 0) {
    this.quantity.remaining = this.quantity.received - this.quantity.sold;
  }
  next();
});

// 实例方法：增加查看次数
teaBatchSchema.methods.incrementViews = function() {
  this.views += 1;
  return this.save();
};

// 实例方法：更新状态
teaBatchSchema.methods.updateStatus = function(newStatus) {
  this.status = newStatus;
  return this.save();
};

// 静态方法：根据用户查找批次
teaBatchSchema.statics.findByUser = function(userId, role) {
  const query = {};
  
  switch (role) {
    case 'farmer':
      query['production.farmerId'] = userId;
      break;
    case 'logistics':
      query['logistics.logisticsId'] = userId;
      break;
    case 'merchant':
      query['sales.merchantId'] = userId;
      break;
    default:
      query.createdBy = userId;
  }
  
  return this.find(query);
};

// 静态方法：搜索批次
teaBatchSchema.statics.searchBatches = function(searchTerm) {
  return this.find({
    $text: { $search: searchTerm },
    isPublic: true
  }).sort({ score: { $meta: 'textScore' } });
};

// 静态方法：获取统计信息
teaBatchSchema.statics.getStatistics = function() {
  return this.aggregate([
    {
      $group: {
        _id: null,
        totalBatches: { $sum: 1 },
        byStatus: {
          $push: {
            status: '$status',
            count: 1
          }
        },
        byVariety: {
          $push: {
            variety: '$variety',
            count: 1
          }
        },
        avgQualityScore: { $avg: '$qualityScore' },
        totalViews: { $sum: '$views' }
      }
    }
  ]);
};

module.exports = mongoose.model('TeaBatch', teaBatchSchema);